package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"time"
)

type GitLabUser struct {
	Username string `json:"username"`
	Email    string `json:"email"`
}

func main() {
	sourceToken := "HCstvVFe8E5RVCcnh1Tj"
	targetToken := "moqTwavKxp6f1tiihV_n"
	sourceURL := "http://192.168.23.128:20021/api/v4/users"
	targetURL := "http://192.168.23.128:20023/api/v4/users"

	rand.Seed(time.Now().UnixNano()) // Initialize random seed

	sourceUsers, err := getUsers(sourceURL, sourceToken)
	if err != nil {
		fmt.Println("Error getting source users:", err)
		return
	}

	fixedPassword := "Ythpt5566"
	for _, user := range sourceUsers {
		userData := GitLabUser{
			Username: user.Username,
			Email:    user.Email,
		}
		err := createUser(targetURL, targetToken, userData, fixedPassword)
		if err != nil {
			fmt.Printf("Error creating user %s in target GitLab: %v\n", user.Username, err)
		} else {
			fmt.Printf("User %s created in target GitLab with password: %s\n", user.Username, fixedPassword)
		}
	}
}

func getUsers(apiURL, token string) ([]GitLabUser, error) {
	req, err := http.NewRequest("GET", apiURL, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("PRIVATE-TOKEN", token)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var users []GitLabUser
	err = json.NewDecoder(resp.Body).Decode(&users)
	if err != nil {
		return nil, err
	}

	return users, nil
}

func createUser(apiURL, token string, user GitLabUser, password string) error {
	data := map[string]interface{}{
		"username":          user.Username,
		"email":             user.Email,
		"password":          password,
		"name":              user.Username,
		"skip_confirmation": true,
	}

	dataBytes, err := json.Marshal(data)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(dataBytes))
	if err != nil {
		return err
	}
	req.Header.Add("PRIVATE-TOKEN", token)
	req.Header.Add("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusCreated {
		respBody, _ := ioutil.ReadAll(resp.Body)
		return fmt.Errorf("unexpected response: %s\nResponse Body: %s", resp.Status, respBody)
	}

	return nil
}
